using System;
using System.Collections.Generic;
using System.Linq;
using SharePoint.Security.ConfigAnalyzer.Engine.Common;
using System.Reflection;

namespace SharePoint.Security.ConfigAnalyzer.Engine.Base
{
    public class BaseRuleSet : IRuleSet
    {
        #region Properties
        public string Title { get; set; }

        public Status OverAllStatus
        {
            get
            {
                if (Rules != null)
                {
                    if (Rules.Any(c => c.Status == Status.Fail))
                    {
                        return Status.Fail;
                    }
                    if (Rules.All(c => c.Status == Status.Pass))
                    {
                        return Status.Pass;
                    }
                    return Status.InConclusive;
                }
                return Status.InConclusive;
            }
        }

        public string Description { get; set; }

        public List<BaseRule> Rules { get; set; }

        #endregion

        #region Implementation of IRuleSet

        public virtual void Validate()
        {
            foreach (var rule in Rules)
            {
                try
                {
                    rule.Validate();
                }
                catch (Exception ex)
                {
                    rule.Status = Status.InConclusive;
                    rule.CurrentValue = string.Format("Error occurred while trying to fetch value. Error: {0}", ex.ToString());
                }
            }
        }

        public virtual void SetUp(string nameSpace)
        {
            Rules = new List<BaseRule>();
            
            var q = from t in Assembly.GetExecutingAssembly().GetTypes()

                    where t.IsSubclassOf(typeof(Base.BaseRule)) && t.Namespace == nameSpace
                    select t;


            foreach (var type in q)
            {
                var instance = (Base.BaseRule)Activator.CreateInstance(type);
                Rules.Add(instance);
            }
        }

        #endregion
    }
}